package com.ffcs.crmd.tsp.admin.web.api.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.ctg.itrdc.platform.common.entity.PageInfo;
import com.ctg.itrdc.platform.common.log.ILogger;
import com.ctg.itrdc.platform.common.log.LoggerFactory;
import com.ctg.itrdc.platform.common.utils.json.JSONUtils;
import com.ctg.itrdc.platform.common.utils.type.StringUtils;
import com.ffcs.crmd.platform.pub.vo.RetVo;

public class HttpUtils {
    
    private static final ILogger logger = LoggerFactory.getLogger(HttpUtils.class);
    
    
    /**
     * 
     * 功能说明:post请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数内容（json格式）
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpPost(String url, String params) throws Exception {
        return httpPost(url, params, -1, -1, -1);
    }
    
    
    /**
     * 
     * 功能说明:post请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数对象（内部转换成json格式）
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpPost(String url, Object params) throws Exception {
        return httpPost(url, params, -1, -1, -1);
    }
    
    
    /**
     * 
     * 功能说明:post请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数内容
     * @param connectTimeout
     *      设置连接超时时间   
     * @param conncectionRequestTimeout
     *      设置从connect Manager获取Connection 超时时间
     * @param socketTimeout
     *      请求获取数据的超时时间   
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     * 
     * @throws Exception 
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpPost(String url, Map<String, String> params) throws Exception {
        return httpPost(url, params, -1, -1, -1);
    }
    
    /**
     * 
     * 功能说明:post请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数内容（json格式）
     * @param connectTimeout
     *      设置连接超时时间   
     * @param conncectionRequestTimeout
     *      设置从connect Manager获取Connection 超时时间
     * @param socketTimeout
     *      请求获取数据的超时时间   
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpPost(String url, String params, int connectTimeout, int conncectionRequestTimeout, int socketTimeout) throws Exception {
        String[] result = {"", ""};
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httppost = new HttpPost(url);
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(conncectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build(); 
            
            StringEntity stringEntity = new StringEntity(JSON.toJSONString(JSON.parse(params)), "utf-8");
            stringEntity.setContentEncoding("UTF-8");
            stringEntity.setContentType("application/json");
            httppost.setEntity(stringEntity);
            httppost.setConfig(requestConfig);
            
            CloseableHttpResponse httpResponse = closeableHttpClient.execute(httppost);
            result[0] = String.valueOf(httpResponse.getStatusLine().getStatusCode());
            try {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null){
                    result[1] = EntityUtils.toString(entity, "UTF-8");
                }
            } finally {
                httpResponse.close();
            }
        } catch (Exception e) {
            logger.error("HttpUtils post request exception : ", e);
        } finally {
            try {
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error("HttpUtils post request close exception", e);
            }
        }
        return result;
    }
  
    
    /**
     * 
     * 功能说明:post请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数对象（内部转换成json格式）
     * @param connectTimeout
     *      设置连接超时时间   
     * @param conncectionRequestTimeout
     *      设置从connect Manager获取Connection 超时时间
     * @param socketTimeout
     *      请求获取数据的超时时间        
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpPost(String url, Object params, int connectTimeout, int conncectionRequestTimeout, int socketTimeout) throws Exception {
        String[] result = {"", ""};
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httppost = new HttpPost(url);
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(conncectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build(); 
            
            StringEntity stringEntity = new StringEntity(JSON.toJSONString(params), "utf-8");
            stringEntity.setContentEncoding("UTF-8");
            stringEntity.setContentType("application/json");
            httppost.setEntity(stringEntity);
            httppost.setConfig(requestConfig);
            
            CloseableHttpResponse httpResponse = closeableHttpClient.execute(httppost);
            result[0] = String.valueOf(httpResponse.getStatusLine().getStatusCode());
            try {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null){
                    result[1] = EntityUtils.toString(entity, "UTF-8");
                }
            } finally {
                httpResponse.close();
            }
        } catch (Exception e) {
            logger.error("HttpUtils post request exception : ", e);
        } finally {
            try {
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error("HttpUtils post request close exception", e);
            }
        }
        return result;
    }
    
    
    /**
     * 
     * 功能说明:post请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数内容
     * @param connectTimeout
     *      设置连接超时时间   
     * @param conncectionRequestTimeout
     *      设置从connect Manager获取Connection 超时时间
     * @param socketTimeout
     *      请求获取数据的超时时间   
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpPost(String url, Map<String, String> params, int connectTimeout, int conncectionRequestTimeout, int socketTimeout) {
        String[] result = {"", ""};
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpPost httppost = new HttpPost(url);
        try {
            List<NameValuePair> paramsPair = new ArrayList<NameValuePair>();
            if ((params != null) && (params.size() > 0)) {
                for (Entry<String, String> entry : params.entrySet()) {
                    BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), entry.getValue());
                    paramsPair.add(nameValuePair);
                }
            }
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(conncectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build();
            
            UrlEncodedFormEntity stringEntity = new UrlEncodedFormEntity(paramsPair, "utf-8");
            stringEntity.setContentEncoding("UTF-8");
            stringEntity.setContentType("application/text");
            httppost.setEntity(stringEntity);
            httppost.setConfig(requestConfig);
            
            CloseableHttpResponse httpResponse = closeableHttpClient.execute(httppost);
            result[0] = String.valueOf(httpResponse.getStatusLine().getStatusCode());;
            try {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null){
                    result[1] = EntityUtils.toString(entity, "UTF-8");
                }
            } finally {
                httpResponse.close();
            }
        } catch (Exception e) {
            logger.error("HttpUtils post request exception : ", e);
        } finally {
            try {
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error("HttpUtils post request close exception", e);
            }
        }
        return result;
    }
    
    /**
     * 
     * 功能说明:get请求
     * 
     * @param url
     *      请求地址
     * @return isReachable
     *      是否连接成功
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static boolean httpGet(String url) {
        return httpGet(url, -1, -1, -1);
    }
    
    /**
     * 
     * 功能说明:get请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数内容
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpGet(String url, Map<String, String> params) {
        return httpGet(url, params, -1, -1, -1);
    }
    
    /**
     * 
     * 功能说明:get请求
     * 
     * @param url
     *      请求地址
     * @param connectTimeout
     *      设置连接超时时间   
     * @param conncectionRequestTimeout
     *      设置从connect Manager获取Connection 超时时间
     * @param socketTimeout
     *      请求获取数据的超时时间   
     * @return isReachable
     *      是否连接成功
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static boolean httpGet(String url, int connectTimeout, int conncectionRequestTimeout, int socketTimeout) {
        boolean isReachable = false;
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
        HttpGet httpGet = new HttpGet(url);
        try {
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(conncectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build();
            httpGet.setConfig(requestConfig);
            CloseableHttpResponse httpResponse = closeableHttpClient.execute(httpGet);
            try{
                if (httpResponse.getStatusLine().getStatusCode() == 200){
                    isReachable = true;
                }
            }finally{
                httpResponse.close();
            }
        } catch (Exception e) {
            isReachable = false;
            logger.error("HttpUtils get request exception : ", e);
        } finally {
            try {
                closeableHttpClient.close();
            } catch (IOException e) {
                logger.error("HttpUtils get request close exception", e);
            }
        }
        
        return isReachable;
    }

    
    /**
     * 
     * 功能说明:get请求
     * 
     * @param url
     *      请求地址
     * @param params
     *      请求参数内容
     * @param connectTimeout
     *      设置连接超时时间   
     * @param conncectionRequestTimeout
     *      设置从connect Manager获取Connection 超时时间
     * @param socketTimeout
     *      请求获取数据的超时时间   
     * @return result
     *      result[0]:请求结果状态 ，result[1]:请求结果内容
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    public static String[] httpGet(String url, Map<String, String> params, int connectTimeout, int conncectionRequestTimeout, int socketTimeout) {
        String[] result = {"", ""};
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            boolean first = true;
            StringBuilder request = new StringBuilder(url);
            if ((params != null) && (params.size() > 0)) {
                for (Entry<String, String> entry : params.entrySet()) {
                    if (first) {
                        request.append("?");
                        request.append(entry.getKey());
                        request.append("=");
                        request.append(StringUtils.strnull(entry.getValue()));
                        first = false;
                    } else {
                        request.append("&");
                        request.append(entry.getKey());
                        request.append("=");
                        request.append(StringUtils.strnull(entry.getValue()));
                    }
                }
                
            }
            
            HttpGet httpGet = new HttpGet(request.toString());
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(conncectionRequestTimeout)
                .setSocketTimeout(socketTimeout).build();
            httpGet.setConfig(requestConfig);
            CloseableHttpResponse httpResponse = httpclient.execute(httpGet);
            result[0] = String.valueOf(httpResponse.getStatusLine().getStatusCode());
            try {
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null){
                    result[1] = EntityUtils.toString(entity, "UTF-8");
                }
            } finally {
                httpResponse.close();
            }
        } catch (Exception e) {
            logger.error("HttpUtils get request exception : ", e);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                logger.error("HttpUtils get request close exception", e);
            }
        }
        return result;
    }
    
    
    /**
     * 
     * 功能说明:get请求
     * 
     * @param result
     *      json结果对象
     * @param classes
     *      结果对象类型
     * @return RetVo
     *      标准结果
     * @author ZHONGFUHUA
     *
     * @Date 2016年11月24日
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> RetVo convert(Object result, Class<T> classes) {
        Map<String, Object> map = (Map<String, Object>) result;
        RetVo retVo = new RetVo(true);
        retVo.setResult(Boolean.valueOf(String.valueOf(map.get("result"))));
        retVo.setRetCode(String.valueOf(map.get("retCode")));
        retVo.setDetailMsg(String.valueOf(map.get("detailMsg")));
        retVo.setObject(map.get("object"));
        retVo.setExceptions((Throwable) JSONUtils.jsonToObject(String.valueOf(map.get("exceptions")), Throwable.class));
        
        List<T> collection = JSONUtils.jsonToObject(String.valueOf(map.get("dataList")), Collection.class);
        if (collection != null) {
            List<T> list = new ArrayList<T>();
            for (Object object : collection) {
                list.add((T) JSONUtils.jsonToObject(String.valueOf(object), classes));
            }
            retVo.setDataList(list);
        }
        
        PageInfo<T> pageInfo = JSONUtils.jsonToObject(String.valueOf(map.get("pageInfo")), PageInfo.class);
        if (pageInfo!=null && pageInfo.getList() != null) {
            List<T> list = new ArrayList<T>();
            for (Object object : pageInfo.getList()) {
                list.add((T) JSONUtils.jsonToObject(String.valueOf(object), classes));
            }
            pageInfo.setList(list);
        }
        retVo.setPageInfo(pageInfo);
        retVo.setExceptionPath(String.valueOf(map.get("exceptionPath")));
        return retVo;
    }
    
}
